<template>
	<view class="card itinerary" :class="{ 'multi-card': business_type === 60 }" v-if="itinerary_infos?.length">
		<view class="card-title">行程</view>
		<template v-if="business_type === 50">
			<view class="one-day-tour" v-for="(item, index) in itinerary_infos" :key="index">
				<view class="itinerary-item" v-for="(_item, _index) in item.items" :key="_index">
					<view class="title">{{ formatTime(_item.start_time) }}</view>
					<view class="right-section">
						<view class="top">
							<image :src="getIconUrl(_item.item_type)" class="icon" />
							<text class="title">{{ _item.title }}</text>
						</view>
						<view class="content">
							<view class="description" v-if="_item.description">{{ _item.description }}</view>
							<view class="tips">
								<image :src="`${imgBaseUrl}time-icon.png`" class="time-icon" />
								<text class="text">
									占用时间：约{{ _item.hours ? `${_item.hours}小时` : ""
									}}{{ _item.minutes ? `${_item.minutes}分钟` : "" }}
								</text>
							</view>
						</view>
					</view>
				</view>
			</view>
			<view class="bottom-tips">
				<image :src="`${imgBaseUrl}tips-icon.png`" class="tips-icon" />
				<text class="text">提示：以上行程安排可能会根据当天实际情况进行适当调整</text>
			</view>
		</template>

		<view v-if="business_type === 60" class="multi-day-tour">
			<view class="day-left" :style="dayLeftStyle">
				<view
					class="day-left-item"
					:class="{ checked: index === checkedIndex }"
					v-for="(item, index) in itinerary_infos"
					:key="index"
					@click="handleDayLeftClick(index)"
				>
					第{{ item.days }}天
				</view>
			</view>
			<view class="content-right">
				<view class="content-right-item" v-for="(item, index) in itinerary_infos" :key="index">
					<view class="header">
						<view class="days">
							<text class="days-text">第{{ item.days }}天</text>
						</view>
						<text class="divider"></text>
						<text class="destination">{{ item.destination }}</text>
					</view>
					<view class="item" v-for="(_item, _index) in item.items" :key="_index">
						<view class="title">{{ formatTime(_item.start_time) }}</view>
						<view class="right-section">
							<view class="top">
								<image :src="getIconUrl(_item.item_type)" class="icon" />
								<text class="title">{{ _item.title }}</text>
							</view>
							<view class="content">
								<view class="description" v-if="_item.description">{{ _item.description }}</view>
								<view class="tips">
									<image :src="`${imgBaseUrl}time-icon.png`" class="time-icon" />
									<text class="text">
										占用时间：约{{ _item.hours ? `${_item.hours}小时` : ""
										}}{{ _item.minutes ? `${_item.minutes}分钟` : "" }}
									</text>
								</view>
							</view>
						</view>
					</view>
				</view>
				<view class="bottom-tips">
					<image :src="`${imgBaseUrl}tips-icon.png`" class="tips-icon" />
					<text class="text">提示：以上行程安排可能会根据当天实际情况进行适当调整</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script setup lang="ts">
enum ItemType {
	/** 大交通 */
	GreatTransportation = 10,
	/** 集合点 */
	MarshalPoint = 20,
	/** 交通 */
	Traffic = 30,
	/** 活动景点 */
	EventAttractions = 40,
	/** 用餐 */
	Meals = 50,
	/** 住宿 */
	Accommodation = 60,
	/** 自由活动 */
	FreeActivities = 70,
	/** 购物点 */
	ShoppingPoints = 80,
	/** 其他 */
	Other = 90,
}

interface Item {
	// 开始时间
	start_time: string
	item_type: ItemType
	title: string
	description: string
	hours: number
	minutes: number
}

interface ItineraryInfo {
	days: number
	// 目的地，多日游时存在
	destination: string
	items: Item[]
}

interface ItineraryProps {
	/** 50: 一日游 60: 多日游 */
	business_type: 50 | 60
	itinerary_infos: ItineraryInfo[]
}

import { ref, getCurrentInstance, computed, onMounted } from "vue"
import { onPageScroll } from "@dcloudio/uni-app"
import useCommonStore from "@/store/common"
let timer: number | undefined = undefined

const imgBaseUrl = inject("imgBaseUrl")
const instance = getCurrentInstance()
const commonStore = useCommonStore()

const props = defineProps<ItineraryProps>()

const contentRightItemTops = ref<number[]>([])
const checkedIndex = ref(0)
const isTabChange = ref(false)

const dayLeftStyle = computed(() => ({
	top: `${commonStore.navbarHeight + commonStore.statusBarHeight + uni.upx2px(186)}px`,
}))

const formatTime = (time?: string) => {
	if (time) {
		const arr = time.split(":")

		return arr.slice(0, 2).join(":")
	}

	return ""
}

const getIconUrl = (item_type: ItemType) => {
	const str = {
		[ItemType.GreatTransportation]: "itinerary-30",
		[ItemType.MarshalPoint]: "itinerary-20",
		[ItemType.Traffic]: "itinerary-30",
		[ItemType.EventAttractions]: "itinerary-40",
		[ItemType.Meals]: "itinerary-50",
		[ItemType.Accommodation]: "itinerary-60",
		[ItemType.FreeActivities]: "itinerary-40",
		[ItemType.ShoppingPoints]: "itinerary-80",
		[ItemType.Other]: "itinerary-90",
	}[item_type]

	return `${imgBaseUrl}${str}.png`
}

const handleDayLeftClick = (idx: number) => {
	if (checkedIndex.value === idx) return

	if (timer) clearTimeout(timer)

	isTabChange.value = true

	checkedIndex.value = idx

	uni.pageScrollTo({
		scrollTop: contentRightItemTops.value[idx],
		complete: () => {
			;(timer as unknown as NodeJS.Timeout) = setTimeout(() => {
				isTabChange.value = false
				clearTimeout(timer)
			}, 500)
		},
	})
}

onMounted(() => {
	if (props.business_type === 60) {
		uni.createSelectorQuery()
			.in(instance)
			.selectAll(".content-right-item")
			.boundingClientRect((data) => {
				contentRightItemTops.value = (data as UniApp.NodeInfo[]).map(
					(item) =>
						(item.top || 0) - (uni.upx2px(186) + commonStore.navbarHeight + commonStore.statusBarHeight)
				)
			})
			.exec()
	}
})

onPageScroll(({ scrollTop }) => {
	if (isTabChange.value) return

	const index = contentRightItemTops.value.findIndex((item) => item > scrollTop)

	if (index === -1) {
		checkedIndex.value = contentRightItemTops.value.length - 1
	}

	if (index > 0) {
		checkedIndex.value = index - 1
	}

	if (index === 0) {
		checkedIndex.value = index
	}
})
</script>

<style lang="scss" scoped>
@import "../../ticket/index.scss";

.itinerary {
	.card-title {
		margin-bottom: 32rpx;
	}

	.title {
		font-weight: 500;
		font-size: 28rpx;
		color: #1d2129;
		line-height: 40rpx;
	}

	.one-day-tour {
		.itinerary-item {
			display: flex;
			align-items: flex-start;

			.right-section {
				position: relative;
				flex: 1;
				margin-left: 16rpx;

				&::before {
					content: "";
					position: absolute;
					// 16rpx 为 .icon 宽度的一半
					left: 16rpx;
					top: 40rpx;
					// 48rpx 为 .icon 的高度 32rpx 加上上下的 8rpx 间距
					height: calc(100% - 48rpx);
					border-right: 1rpx dashed #e5e6eb;
				}

				.top {
					display: flex;
					align-items: flex-start;

					.icon {
						flex-shrink: 0;
						width: 32rpx;
						height: 32rpx;
						margin-right: 16rpx;
						margin-top: 4rpx;
					}
				}

				.content {
					padding-top: 16rpx;
					padding-bottom: 60rpx;
					padding-left: 48rpx;

					.description {
						margin-bottom: 24rpx;
						font-size: 24rpx;
						color: #86909c;
						line-height: 36rpx;
					}

					.tips {
						display: flex;
						align-items: center;
						padding: 16rpx 24rpx 14rpx;
						background: #f7f8fa;
						border-radius: 16rpx;

						.time-icon {
							width: 28rpx;
							height: 28rpx;
							margin-right: 12rpx;
						}

						.text {
							font-size: 24rpx;
							color: #1d2129;
							line-height: 34rpx;
						}
					}
				}
			}

			&:last-child {
				.right-section {
					&::before {
						content: none;
					}

					.content {
						padding-bottom: 0;
					}
				}
			}
		}
	}

	.multi-day-tour {
		display: flex;
		height: max-content;
		background-color: #f1f2f5;

		.day-left {
			width: 120rpx;
			height: max-content;
			position: sticky;
			background-color: #f1f2f5;

			.day-left-item {
				padding: 32rpx 24rpx;
				font-size: 24rpx;
				color: #1d2129;
				line-height: 48rpx;

				&.checked {
					background-color: #fff;
					font-weight: 600;
				}
			}
		}

		.content-right {
			flex: 1;
			padding-left: 16rpx;
			background-color: #fff;

			.content-right-item {
				padding: 40rpx 24rpx;
				background-color: rgba(247, 248, 250, 0.5);
				border-radius: 16rpx;

				&:not(:last-child) {
					margin-bottom: 16rpx;
				}

				.header {
					display: flex;
					align-items: center;
					margin-bottom: 32rpx;

					.days {
						position: relative;
						font-weight: 600;
						font-size: 28rpx;
						color: #1d2129;
						line-height: 40rpx;

						&::after {
							content: "";
							position: absolute;
							left: 0;
							bottom: 0;
							width: 100%;
							height: 10rpx;
							background-color: #fee038;
							z-index: 0;
						}

						.days-text {
							position: relative;
							z-index: 1;
						}
					}

					.divider {
						width: 2rpx;
						height: 24rpx;
						margin: 0 16rpx;
						background-color: #e5e5e8;
					}

					.destination {
						font-weight: 600;
						font-size: 28rpx;
						color: #1d2129;
						line-height: 40rpx;
					}
				}

				.item {
					display: flex;
					align-items: flex-start;

					.right-section {
						position: relative;
						flex: 1;
						margin-left: 16rpx;

						&::before {
							content: "";
							position: absolute;
							// 16rpx 为 .icon 宽度的一半
							left: 16rpx;
							top: 40rpx;
							// 48rpx 为 .icon 的高度 32rpx 加上上下的 8rpx 间距
							height: calc(100% - 48rpx);
							border-right: 1rpx dashed #e5e6eb;
						}

						.top {
							display: flex;
							align-items: flex-start;

							.icon {
								flex-shrink: 0;
								width: 32rpx;
								height: 32rpx;
								margin-right: 16rpx;
								margin-top: 4rpx;
							}
						}

						.content {
							padding-top: 16rpx;
							padding-bottom: 60rpx;
							padding-left: 48rpx;

							.description {
								margin-bottom: 24rpx;
								font-size: 24rpx;
								color: #86909c;
								line-height: 36rpx;
							}

							.tips {
								display: flex;
								align-items: center;
								padding: 16rpx 24rpx 14rpx;
								background: #f7f8fa;
								border-radius: 16rpx;

								.time-icon {
									width: 28rpx;
									height: 28rpx;
									margin-right: 12rpx;
								}

								.text {
									font-size: 24rpx;
									color: #1d2129;
									line-height: 34rpx;
								}
							}
						}
					}

					&:last-child {
						.right-section {
							&::before {
								content: none;
							}

							.content {
								padding-bottom: 0;
							}
						}
					}
				}
			}
		}
	}

	.bottom-tips {
		display: flex;
		align-items: flex-start;
		padding: 24rpx;
		margin-top: 28rpx;
		background-color: rgba(255, 179, 0, 0.1);
		border-radius: 16rpx;

		.tips-icon {
			flex-shrink: 0;
			width: 28rpx;
			height: 28rpx;
			margin-top: 8rpx;
		}

		.text {
			margin-left: 8rpx;
			font-size: 26rpx;
			color: #bc8400;
			line-height: 40rpx;
		}
	}
}

.multi-card {
	padding-left: 0;

	.card-title {
		padding-left: 24rpx;
	}
}
</style>
